{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "f04dd603-a2d1-48ce-8c17-9f1dba8de1ee",
   "metadata": {},
   "source": [
    "Chapter 01\n",
    "\n",
    "# 向量夹角\n",
    "《线性代数》 | 鸢尾花书：数学不难"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ccafb456-2453-4c82-8a65-b1963a370cb2",
   "metadata": {},
   "source": [
    "该代码的主要目的是计算两个三维向量 $ \\mathbf{v}_1 $ 和 $ \\mathbf{v}_2 $ 之间的夹角，使用了内积（点积）和范数（向量的模长），并通过余弦定理计算夹角的弧度值和角度值。\n",
    "\n",
    "---\n",
    "\n",
    "### **向量定义**\n",
    "代码定义了两个向量：\n",
    "$$\n",
    "\\mathbf{v}_1 = \\begin{bmatrix} 1 \\\\ 1 \\\\ 0 \\end{bmatrix}, \\quad\n",
    "\\mathbf{v}_2 = \\begin{bmatrix} 0 \\\\ 1 \\\\ 1 \\end{bmatrix}\n",
    "$$\n",
    "这两个向量位于三维空间中。\n",
    "\n",
    "---\n",
    "\n",
    "### **计算向量的内积**\n",
    "向量的内积（点积）定义为：\n",
    "$$\n",
    "\\mathbf{v}_1 \\cdot \\mathbf{v}_2 = v_{1x} v_{2x} + v_{1y} v_{2y} + v_{1z} v_{2z}\n",
    "$$\n",
    "代入具体值：\n",
    "$$\n",
    "1 \\cdot 0 + 1 \\cdot 1 + 0 \\cdot 1 = 0 + 1 + 0 = 1\n",
    "$$\n",
    "因此，代码计算的点积值为：\n",
    "$$\n",
    "\\text{dot\\_product} = 1\n",
    "$$\n",
    "\n",
    "---\n",
    "\n",
    "### **计算向量的范数**\n",
    "向量的范数（模长）定义为：\n",
    "$$\n",
    "\\|\\mathbf{v}_1\\| = \\sqrt{v_{1x}^2 + v_{1y}^2 + v_{1z}^2}\n",
    "$$\n",
    "$$\n",
    "\\|\\mathbf{v}_2\\| = \\sqrt{v_{2x}^2 + v_{2y}^2 + v_{2z}^2}\n",
    "$$\n",
    "分别计算：\n",
    "$$\n",
    "\\|\\mathbf{v}_1\\| = \\sqrt{1^2 + 1^2 + 0^2} = \\sqrt{2}\n",
    "$$\n",
    "$$\n",
    "\\|\\mathbf{v}_2\\| = \\sqrt{0^2 + 1^2 + 1^2} = \\sqrt{2}\n",
    "$$\n",
    "所以，代码中计算的模长：\n",
    "$$\n",
    "\\text{norm1} = \\sqrt{2}, \\quad \\text{norm2} = \\sqrt{2}\n",
    "$$\n",
    "\n",
    "---\n",
    "\n",
    "### **计算余弦值**\n",
    "根据余弦定理，两个向量夹角的余弦值可以表示为：\n",
    "$$\n",
    "\\cos\\theta = \\frac{\\mathbf{v}_1 \\cdot \\mathbf{v}_2}{\\|\\mathbf{v}_1\\| \\|\\mathbf{v}_2\\|}\n",
    "$$\n",
    "代入具体计算：\n",
    "$$\n",
    "\\cos\\theta = \\frac{1}{\\sqrt{2} \\times \\sqrt{2}} = \\frac{1}{2}\n",
    "$$\n",
    "因此，代码中计算的余弦值为：\n",
    "$$\n",
    "\\text{cos\\_theta} = 0.5\n",
    "$$\n",
    "\n",
    "---\n",
    "\n",
    "### **计算夹角（弧度）**\n",
    "夹角 $\\theta$ 的弧度值通过反余弦（$\\arccos$）函数计算：\n",
    "$$\n",
    "\\theta = \\arccos(\\cos\\theta)\n",
    "$$\n",
    "代入具体值：\n",
    "$$\n",
    "\\theta = \\arccos(0.5)\n",
    "$$\n",
    "由反余弦函数的性质：\n",
    "$$\n",
    "\\arccos(0.5) = \\frac{\\pi}{3} \\text{（弧度）}\n",
    "$$\n",
    "因此，代码计算出的弧度值：\n",
    "$$\n",
    "\\text{theta\\_rad} = \\frac{\\pi}{3} \\approx 1.047 \\text{（单位：弧度）}\n",
    "$$\n",
    "\n",
    "---\n",
    "\n",
    "### **计算夹角（角度）**\n",
    "弧度转换为角度使用公式：\n",
    "$$\n",
    "\\theta_{\\text{deg}} = \\theta_{\\text{rad}} \\times \\frac{180}{\\pi}\n",
    "$$\n",
    "代入计算：\n",
    "$$\n",
    "\\theta_{\\text{deg}} = \\frac{\\pi}{3} \\times \\frac{180}{\\pi} = 60^\\circ\n",
    "$$\n",
    "所以，代码计算出的角度值：\n",
    "$$\n",
    "\\text{theta\\_deg} = 60^\\circ\n",
    "$$\n",
    "\n",
    "---\n",
    "\n",
    "### **总结**\n",
    "该代码的核心计算流程是：\n",
    "1. 计算向量内积，结果为 $1$。\n",
    "2. 计算两个向量的模长，均为 $\\sqrt{2}$。\n",
    "3. 计算夹角的余弦值，得到 $\\cos\\theta = 0.5$。\n",
    "4. 通过反余弦函数求得夹角弧度值 $\\frac{\\pi}{3}$。\n",
    "5. 将弧度转换为角度，得到 $\\theta = 60^\\circ$。\n",
    "\n",
    "最终，该代码成功计算出 $\\mathbf{v}_1$ 和 $\\mathbf{v}_2$ 之间的夹角为 $60^\\circ$，验证了向量运算在几何角度上的正确性。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "26e6e3a3-18f5-4574-8d51-4285a44fedc6",
   "metadata": {},
   "source": [
    "## 初始化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "76842e7b-5caa-44fe-8e30-8babc6c51559",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e4c70cb5-42c5-4f75-b95a-9788d2e177f2",
   "metadata": {},
   "source": [
    "## 定义两个向量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "de354f29-e30c-4a85-83f9-a96c995fc1d9",
   "metadata": {},
   "outputs": [],
   "source": [
    "vector1 = np.array([1, 1, 0])\n",
    "vector2 = np.array([0, 1, 1])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea7b47c7-5f2d-46ef-bf57-0faa7385c3cb",
   "metadata": {},
   "source": [
    "## 计算内积"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "028e4a3d-6fc6-4228-8c6b-7c7dbccc36de",
   "metadata": {},
   "outputs": [],
   "source": [
    "dot_product = np.dot(vector1, vector2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc288400-7e65-4284-a43d-e880d3f07de6",
   "metadata": {},
   "source": [
    "## 计算向量长度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "9f87d7ee-b91b-4804-b63b-f4cfa5b8811b",
   "metadata": {},
   "outputs": [],
   "source": [
    "norm1 = np.linalg.norm(vector1)\n",
    "norm2 = np.linalg.norm(vector2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a4457dd8-3c5c-49e9-ac40-3fc8d2820249",
   "metadata": {},
   "source": [
    "## 计算夹角的余弦值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "30794ae4-45e5-4e24-8ac0-8797f285cedc",
   "metadata": {},
   "outputs": [],
   "source": [
    "cos_theta = dot_product / (norm1 * norm2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ec39c240-8e82-489d-9763-a95333109b4e",
   "metadata": {},
   "source": [
    "## 计算夹角（弧度）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "8251cbb4-5477-4dfe-9358-888b65bf4407",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0471975511965979"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "theta_rad = np.arccos(cos_theta)\n",
    "theta_rad"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3452c51d-a5c7-47fc-9164-fa765ce6e424",
   "metadata": {},
   "source": [
    "## 计算夹角（角度）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "9e839324-59d6-4389-96d4-834abdaeb54e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "60.00000000000001"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "theta_deg = np.degrees(theta_rad)\n",
    "theta_deg"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "557240fd-655d-4bdf-bde9-c79d2798ba2a",
   "metadata": {},
   "source": [
    "作者\t**生姜DrGinger**  \n",
    "脚本\t**生姜DrGinger**  \n",
    "视频\t**崔崔CuiCui**  \n",
    "开源资源\t[**GitHub**](https://github.com/Visualize-ML)  \n",
    "平台\t[**油管**](https://www.youtube.com/@DrGinger_Jiang)\t\t\n",
    "\t\t[**iris小课堂**](https://space.bilibili.com/3546865719052873)\t\t\n",
    "\t\t[**生姜DrGinger**](https://space.bilibili.com/513194466)  "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:base] *",
   "language": "python",
   "name": "conda-base-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
